package chabernac.android.wordbattle;

import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import chabernac.android.view.AnimationView;
import chabernac.android.wordbattle.model.Letter;
import chabernac.android.wordbattle.model.Word;
import chabernac.android.wordbattle.model.WordRaster;
import chabernac.android.wordbattle.model.iWordRasterListener;
import chabernac.android.wordbattle.paint.iDrawable;

public class WordBattleView extends AnimationView {
  public final static int BORDER_SIZE = 2;

  private float myWidthPerColumn;
  private float myHeightPerColumn;
  private float mySelectionRadius;
  private ScaleGestureDetector mScaleDetector;
  private float mScaleFactor = 1.f;
  private float xOffset = 0;
  private float yOffset = 0;
  private float xFocus = 0;
  private float yFocus = 0;


  private boolean isScaling = false;

  private WordRasterListener myWordRasterListener = new WordRasterListener();

  private GameDrawerDelegate myGameDrawerDelegate = new GameDrawerDelegate(getDrawableQueue());
  private Paint myPaint = new Paint();

  private WordRaster myWordRaster = null;
  private SelectedLetterHelper mySelectedLetterHelper = null;

  public WordBattleView(Context aContext, AttributeSet aAttrs, int aDefStyle) {
    super(aContext, aAttrs, aDefStyle);
    init(aContext);
  }

  public WordBattleView(Context aContext, AttributeSet aAttrs) {
    super(aContext, aAttrs);
    init(aContext);
  }

  public WordBattleView(Context aContext) {
    super(aContext);
    init(aContext);
  }

  private void init(Context aContext){
    myWordRaster =  WordRasterContext.getInstance().getMediator().getWordRaster();
    mySelectedLetterHelper = new SelectedLetterHelper(myWordRaster);

    setOnTouchListener(new TouchListener());
    myWordRaster.addListener( myWordRasterListener );
    mScaleDetector = new ScaleGestureDetector(aContext, new ScaleListener());
    start();
    drawGame();
    startTimer();
  }

  private void startTimer(){
    if(myWordRaster.getPlayTime() > 0){
      Executors.newScheduledThreadPool( 1 ).schedule( new StopGame(), myWordRaster.getPlayTime(), TimeUnit.SECONDS );
    }
  }

  public float getWidthPerColumn() {
    return myWidthPerColumn;
  }

  public float getHeightPerRow() {
    return myHeightPerColumn;
  }

  public float getSelectionRadius() {
    return mySelectionRadius;
  }


  @Override
  protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
    super.onSizeChanged(xNew, yNew, xOld, yOld);
    calculateSizes();
  }

  private void calculateSizes(){
    if(WordRasterContext.getInstance().getMediator() != null){
      WordRaster theRaster = WordRasterContext.getInstance().getMediator().getWordRaster();
      myWidthPerColumn = ((float)getWidth() - (float)(BORDER_SIZE * 2)) / (float)theRaster.getColumns();

      if(WordRasterContext.getInstance().getMediator().getRenderingHints().isHeightEqualsWidth()){
        myHeightPerColumn = myWidthPerColumn;
      } else {
        myHeightPerColumn = ((float)getHeight() - (float)(BORDER_SIZE * 2)) / (float)theRaster.getRows();
      }
      mySelectionRadius = (float)(Math.min(myHeightPerColumn, myWidthPerColumn) * 0.5 );
    }
  }


  private void selectLetterAt(float anX, float anY){
    int theX = (int) (Math.floor(anX - BORDER_SIZE) / myWidthPerColumn);
    int theY = (int) (Math.floor(anY - BORDER_SIZE) / myHeightPerColumn);
    //    int theY = (int) (Math.floor(anY - BORDER_SIZE) / myWidthPerColumn);

//    System.out.println("selecting letter at " + theX + "," + theY);
    
    WordRaster theWordRaster = WordRasterContext.getInstance().getMediator().getWordRaster();
    if(theWordRaster.getSelectionHelper().isDiagonalSelectionGapNeeded()){
      float theCenterX = BORDER_SIZE + (theX + 0.5F) * myWidthPerColumn ;
      float theCenterY = BORDER_SIZE + (theY + 0.5F) * myHeightPerColumn;
      //      float theCenterY = BORDER_SIZE + (theY + 0.5F) * myWidthPerColumn;

      float theWidth = theCenterX - anX;
      float theHeight = theCenterY - anY;

      float theDistance = (float)Math.sqrt(theWidth *  theWidth + theHeight * theHeight);
      if(theDistance < mySelectionRadius){
        mySelectedLetterHelper.down(theX, theY);
//        theWordRaster.setSelectedLetter(theX, theY, true);
      }
    } else {
      mySelectedLetterHelper.down(theX, theY);
//      theWordRaster.setSelectedLetter(theX, theY, true);
    }
  }

  private void drawGame(){
    WordRaster theWordRaster = WordRasterContext.getInstance().getMediator().getWordRaster();
    iDrawable theGameDrawable = WordRasterContext.getInstance().getMediator().getDrawableFactory().createGameDrawable( theWordRaster ) ;
    myGameDrawerDelegate.drawGame( theGameDrawable );
  }

  public class WordRasterListener implements iWordRasterListener {
    @Override
    public void selectionChanged(List<Letter> aLetters) {
      drawGame();
    }

    @Override
    public void wordFound(Word aWord) {
      myGameDrawerDelegate.startExplodingTextAnimation( aWord.toString() );
    }
  }

  public class TouchListener implements OnTouchListener {

    @Override
    public boolean onTouch(View aArg0, MotionEvent anEvent) {
//      System.out.println("Touch event in wordbattleview at " + anEvent.getX() + "," +  anEvent.getY());
      mScaleDetector.onTouchEvent(anEvent);
      selectLetterAt(anEvent.getX(), anEvent.getY());
      if(anEvent.getAction() == MotionEvent.ACTION_UP){
//        System.out.println("action up");
        mySelectedLetterHelper.up();
//        WordRaster theWordRaster = WordRasterContext.getInstance().getMediator().getWordRaster();
//        theWordRaster.checkForHiddenWord();
      }
      return true;
    }
  }

  public class WordRasterContextListener implements iWordRasterContextListener {

    @Override
    public void wordRasterGameLoaded(WordRasterGameMediator aWordRasterMediator) {
      WordRaster theWordRaster = aWordRasterMediator.getWordRaster();
      theWordRaster = WordRasterContext.getInstance().getMediator().getWordRaster();
      theWordRaster.addListener( myWordRasterListener );
      calculateSizes();
    }
  }

  @Override
  public void onDraw(Canvas canvas) {
//    System.out.println(canvas.getWidth() + "," +  canvas.getHeight());
    //    xOffset = -480;
    //    yOffset = -400;
    canvas.save();
    canvas.translate(xOffset, yOffset);
    canvas.scale(mScaleFactor, mScaleFactor);
    super.onDraw(canvas);
    canvas.restore();
    myPaint.setColor(Color.BLACK);
    canvas.drawCircle(xFocus, yFocus, 4, myPaint);
    canvas.drawCircle(xFocus * mScaleFactor + xOffset, yFocus * mScaleFactor + yOffset, 4, myPaint);
  }

  private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
    @Override
    public boolean onScale(ScaleGestureDetector detector) {

      //s . x - x 
      //          -s . x + x  = x(1-s);

      if(detector.isInProgress()){
        mScaleFactor *= detector.getScaleFactor();
        // Don't let the object get too small or too large.
        mScaleFactor = Math.max(1f, Math.min(mScaleFactor, 5.0f));

//        if(!isScaling){
          xFocus = detector.getFocusX();
          yFocus = detector.getFocusY();
          xOffset = detector.getFocusX() * (1f - mScaleFactor);
          yOffset = detector.getFocusY() * (1f - mScaleFactor);
//        }
        isScaling = true;
      } else {
        isScaling = false;
      }

      invalidate();
      return true;
    }
  }

  public class StopGame implements Runnable {
    @Override
    public void run() {
      Intent settingsActivity = new Intent(WordRasterContext.getInstance().getContext(), WordBattleStatisticsActivity.class);
      WordRasterContext.getInstance().getContext().startActivity(settingsActivity);
    }
  }
}
